package com.example.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.example.common.Result;
import com.example.common.enums.*;
import com.example.exception.CustomException;
import com.example.pojo.entity.*;
import com.example.pojo.vo.CountTopVo;
import com.example.pojo.vo.SaleLineVo;
import com.example.pojo.vo.SaleBarVo;
import com.example.service.*;
import com.example.utils.AccountUtils;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 统计 controller 层
 */
@RestController
@RequestMapping("/count")
public class CountController {

    @Resource
    private PetShopService petShopService;

    @Resource
    private PetService petService;

    @Resource
    private PostService postService;

    @Resource
    private PetOrdersService petOrdersService;

    @Resource
    private GoodsOrdersService goodsOrdersService;

    @Resource
    private PetTypeService petTypeService;

    @GetMapping("/top")
    public Result countTop() {
        // 1.校验当前用户是否是管理员
        this.checkAdmin();

        CountTopVo vo = new CountTopVo();

        // 2.查询审核通过的宠物店
        List<PetShop> shopList = this.petShopService.lambdaQuery()
                .eq(PetShop::getStatus, PetShopStatusEnum.SUCCESS.getName())
                .list();
        if (CollectionUtil.isEmpty(shopList)) {
            vo.setPetShopCount(0L);
        } else {
            vo.setPetShopCount((long) shopList.size());
        }

        // 3.查询上架的宠物
        List<Pet> petList = this.petService.lambdaQuery()
                .eq(Pet::getStatus, "上架")
                .list();
        if (CollectionUtil.isEmpty(petList)) {
            vo.setPetCount(0L);
        } else {
            vo.setPetCount((long) petList.size());
        }

        // 4.查询审核通过的帖子
        List<Post> postList = this.postService.lambdaQuery()
                .eq(Post::getStatus, PostStatusEnum.AUDIT_SUCCESS.getName())
                .list();
        if (CollectionUtil.isEmpty(postList)) {
            vo.setPostCount(0L);
        } else {
            vo.setPostCount((long) postList.size());
        }

        // 5.查询宠物销售额
        vo.setPetSaleAmount(this.petOrdersService.countSale(null, null, null));

        // 6.查询宠物用品销售额
        vo.setGoodsSaleAmount(this.goodsOrdersService.countSale(null, null, null));

        // 7.返回数据
        return Result.success(vo);
    }

    @GetMapping("/sale/line")
    public Result countSaleLine() {
        // 1.校验当前用户是否是管理员
        this.checkAdmin();

        SaleLineVo vo = new SaleLineVo();

        // 2.返回横轴的数据
        Date date = new Date();
        DateTime dateTime = DateUtil.offsetDay(date, -6);
        List<DateTime> dateTimeList = DateUtil.rangeToList(dateTime, date, DateField.DAY_OF_YEAR);
        List<String> dateStrList = dateTimeList.stream().map(DateUtil::formatDate).toList();
        vo.setXTimeData(dateStrList);

        // 3.近7天每一天的销售额，销售额 = 宠物销售额 + 宠物用品销售额
        List<BigDecimal> saleList = new ArrayList<>();
        for (String curDate : dateStrList) {
            // 获取开始和结束时间
            LocalDate localDate = LocalDate.parse(curDate);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String start = localDate.atStartOfDay().format(formatter);
            String end = localDate.atTime(23, 59, 59).format(formatter);
            // 查询某一天的宠物销售额
            BigDecimal petSale = this.petOrdersService.countSale(null, start, end);
            // 查询某一天的宠物用品销售额
            BigDecimal goodsSale = this.goodsOrdersService.countSale(null, start, end);
            saleList.add(petSale.add(goodsSale));
        }
        vo.setYSaleData(saleList);

        // 4.返回数据
        return Result.success(vo);
    }

    @GetMapping("/petTypePie")
    public Result countPetTypeNumber() {
        // 1.校验当前用户是否是管理员
        this.checkAdmin();

        // 2.查询所有宠物类型
        List<PetType> petTypeList = this.petTypeService.lambdaQuery().list();

        List<Map<String, Object>> list = new ArrayList<>();
        // 3.遍历宠物类型，计算各宠物类型的宠物数量
        if (CollectionUtil.isNotEmpty(petTypeList)) {
            Map<String, Object> map;
            for (PetType petType : petTypeList) {
                Long count = this.petService.lambdaQuery()
                        .eq(Pet::getTypeId, petType.getId())
                        .count();
                map = new HashMap<>();
                map.put("name", petType.getName());
                map.put("value", count);
                list.add(map);
            }
        }

        // 4.返回数据
        return Result.success(list);
    }

    @GetMapping("/sale/bar")
    public Result countSaleBar() {
        // 1.校验当前用户是否是管理员
        this.checkAdmin();

        SaleBarVo vo = new SaleBarVo();

        // 2.查询审核通过的宠物店
        List<PetShop> shopList = this.petShopService.lambdaQuery()
                .eq(PetShop::getStatus, PetShopStatusEnum.SUCCESS.getName())
                .list();

        // 3.遍历每个宠物店计算销售额
        List<String> shopNameList = new ArrayList<>();
        List<BigDecimal> saleList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(shopList)) {
            for (PetShop petShop : shopList) {
                BigDecimal petSale = this.petOrdersService.countSale(petShop.getId(), null, null);
                BigDecimal goodsSale = this.goodsOrdersService.countSale(petShop.getId(), null, null);
                BigDecimal totalSale = petSale.add(goodsSale);
                shopNameList.add(petShop.getName());
                saleList.add(totalSale);
            }
        }

        vo.setXShopNameData(shopNameList);
        vo.setYSaleData(saleList);

        // 4.返回数据
        return Result.success(vo);
    }

    /**
     * 校验当前用户是否是管理员
     */
    private void checkAdmin() {
        Account currentLoginAccount = AccountUtils.getCurrentLoginAccount();
        if(currentLoginAccount == null) {
            throw new CustomException(ErrorCodeEnum.GET_CUR_USER_ERROR);
        }
        if (!RoleEnum.ADMIN.name().equals(currentLoginAccount.getRole())) {
            throw new CustomException(ErrorCodeEnum.ONLY_ADMIN_COUNT);
        }
    }
}
